模版方法【TemplateMethod】

实例

// 对甲乙两名同学所抄试卷,尽量将相同的部分提到父类
// 金庸小说考题试卷
class TestPaper
{
    public function TestQuestion1()
    {
        echo <<<EOF
杨过说过,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是()
    A.球磨铸铁 
    B.马口铁 
    C.高速合金钢 
    D.碳素纤维', PHP_EOL;
EOF
        , PHP_EOL;
        echo '答案 ', $this->answer1(), PHP_EOL;
    }
    public function TestQuestion2()
    {
        echo <<<EOF
杨过、程英、陆无双铲除了情花,造成()
    A.使这种植物不在害人 
    B.使一种珍惜物种灭绝 
    C.破坏了那个生态圈的生态平衡 
    D.造成该地区沙漠化', PHP_EOL;
EOF
        , PHP_EOL;
        echo '答案 ', $this->answer2(), PHP_EOL;
    }
    public function TestQuestion3()
    {
        echo <<<EOF
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药()
    A.阿司匹林 
    B.牛黄解毒片 
    C.氟哌酸 
    D.让他们喝大量的生牛奶
EOF
        , PHP_EOL;
        echo '答案 ', $this->answer3(), PHP_EOL;
    }
    protected function answer1()
    {
        return '';
    }
    protected function answer2()
    {
        return '';
    }
    protected function answer3()
    {
        return '';
    }
}
// 学生甲抄的试卷
class TestPaperA extends TestPaper
{
    protected function answer1()
    {
        return 'A';
    }
    protected function answer2()
    {
        return 'B';
    }
    protected function answer3()
    {
        return 'C';
    }
}
// 学生乙抄的学生甲抄的试卷
class TestPaperB extends TestPaper
{
    protected function answer1()
    {
        return 'D';
    }
    protected function answer2()
    {
        return 'C';
    }
    protected function answer3()
    {
        return 'A';
    }
}
echo '学生甲抄的试卷: ', PHP_EOL;
$student = new TestPaperA();
$student->TestQuestion1();
$student->TestQuestion2();
$student->TestQuestion3();
echo '====华丽的分隔符====', PHP_EOL;
echo '学生乙抄的试卷: ', PHP_EOL;
$student2 = new TestPaperB();
$student2->TestQuestion1();
$student2->TestQuestion2();
$student2->TestQuestion3();

总结

模板方法模式通过在父类中定义固定的算法骨架,将变化的步骤延迟到子类中实现,从而在不改变算法结构的前提下实现了代码的复用和灵活扩展。

意图

定义一个操作中算法的骨架(固定结构),而将其中可变的步骤延迟到子类中实现。

主要解决

解决多个子类中存在重复的通用代码问题,通过提取公共代码到父类实现复用。

何时使用

有一些通用的方法。

如何解决

关键代码

在抽象类实现,其他步骤在子类实现。

优点

缺点

每个不同的实现都需要一个新的子类,可能导致类的数量增加

使用场景

存在多个子类共有的、逻辑相同的方法或步骤;复杂的关键方法需要一个固定的执行流程

注意事项

为防止恶意操作,一般模板方法都加上 final 关键词。